<?php
class TF_Selector
{
    public $nodes;
    public $keys;
    public function  __construct($treebuilder)
    {
        $this->nodes=&$treebuilder->nodes;
        $this->keys=array_keys($this->nodes);
        $this->prepare();  // for getElementById;
    }
    protected function prepare()
    {
        //
    }
    
    public function select($str)
    {
		//^\s*[.\w-][.\w\s\->+~]*(,\s*[.\w-][.\w\s\->+~]*)*$ 
        
        $keys=$this->keys;
        $lastop='init';
        //"#id"
        //".class"
        $ret=$this->keys;
        while($str){
            if('*'==$str{0}){
            }else if(preg_match('/([#.:])?([a-zA-Z0-9_-]+)/A',$str,$m)){
                //
            }else if('['==$str{0} &&  preg_match('/^\[((\\\]|[^\]])+)\]/',$str,$m)){
                //
            }else if(preg_match('/\s*([>+~,]?)\s*/A',$str,$m)){
                if($m[1]==','){
                }else if($m[1]=='>'){
                    //fakeprop":\$child"
                } else if($m[1]=='~'){
                    //fakeprop":\$next"
                }else if(0!=strlen($m[0]){
                    // push externel
                }
               }
            }
            }
            if(0==$match_bytes){
                //error;
                break;
            }
        }
        if($this->external_keys){
            $ret=array_merge($ret,$this->external_keys);
        }
        return $ret;
    }
    protected function explodeClass($str)
    {
        return explode(' ',$str);
    }
    public function getElementById($id,$keys=null)
    {
        if($keys===null){$keys=$this->keys;}
        foreach($key as $key){
            $node=$this->nodes[$key];
            if(isset($node['id'] && $node['id']==$id){
                return array($key);
            }
            
        }
        return array();
    }
    public function getElementsByClass($id,$class,$keys=null)
    {
        if($keys===null){$keys=$this->keys;}
        $ret=array();
        foreach($key as $key){
            $node=$this->nodes[$key];
            if(!isset($node['class']){continue;}
                $classes=$this->explodeClass($node);
                if(in_array($class,$classes)){
                    $ret[]=$key;
                }
            }
        }
        return array();
    }
    public function getElementsByTagName($tagname,$keys=null)
    {
        if($keys===null){$keys=$this->keys;}
        $ret=array();
        
        foreach($key as $key){
            $node=$this->nodes[$key];
            if(isset($node["\$tagname"] && $node["tagname"]==$tagname){
                $ret[]=$key;
            }
            
        }
        return  $ret;
    }
    public function getElementsByAttr($name,$value,$op,$keys=null)
    {
        if($keys===null){$keys=$this->keys;}
        $ret=array();
        
        foreach($key as $key){
            $node=$this->nodes[$key];
            if($op=="\n" && isset($node[$name])){
                $ret[]=$key;
            }else if($op=='*=' && falss!==strpos($node[$name],$value)){
                $ret[]=$key;
            }else if($op=='~=' && in_array($value,$this->explodeClass($node[$name])){
                $ret[]=$key;
            }else if($op=='=' && $node[$name]==$value){
                $ret[]=$key;
            }else if($op=='!=' && $node[$name]!=$value){
                $ret[]=$key;
            }else if($op=='$=' && $value==substr($node[$name],-strlen($value)){
                $ret[]=$key;
            }else if($op=='^=' && $value==substr($node[$name],0,strlen($value)){
                $ret[]=$key;
            }else if($op=='|=' && in_array($value,explode('-',$node[$name])){
                $ret[]=$key;
            }
            // class ,
        }
        return  $ret;
    }
    public function getElmentByFunction($func,$args,$keys)
    {
        switch($prop)
        {
            case 'contains':
                // '' 
            case 'eq':
            case 'gt':
            case 'lt':
            case 'nth-child':
            
            case 'not':
                // ' '

        }
    }
    public function getElementByProperty($prop,$keys)
    {
        switch($prop)
        {
            case 'checkbox':
            
            case 'file':
            case 'hidden':
            case 'password':
            case 'radio':
            case 'reset':
            case 'submit':
            case 'text':
                $this->getElementsByAttr('type',$prop,'=',$keys);
            break;
            case 'checked':
            case 'disabled':
            case 'selected':
            break;
            case 'button':
            case 'input':
            case 'image':
            break;
            case 'even':
            case 'odd':
                
            break;
            case 'empty':
            case 'first-child':
            case 'last-child':
            case 'only-child':
            case 'last':
            case 'parent':
            
        }
    }
    
    function getElementByHierarchy($op,$keys1 ,$keys2)
    {
        switch($op)
        {
            case "\n":
            case '>':
            case ' ':
            case '~':
            case '+':
            case ',':
        }
    }
    
    
    function e()
    {
        $a=array(
            //'*',
            //'[name|=value]',
            //'[name*=value]',
            //'[name~=value]',
            //'[name$=value]',
            //'[name=value]',
            //'[name!=value]',
            //'[name^=value]',
            //':button',
            //':checkbox',
            //':checked',
            'parent>child',
            //'.class',
            //'contains()',
            'ancestor descendant',
            //':disabled',
            ':empty',
            //':enabled',
            ':eq()',
            //':event',
            //':file',
            ':first-child',
            ':gt()',
            '[name]',
            ':has()',
            ':header'
            ':hidden',
            '#id',
            ':image',
            ':input'
            ':last-child',
            ':lt()',
            '[][]',
            'a,b,'
            'prev + next'
            'prev ~ siblings'
            ':not()',
            ':nth-child()'
            ':odd',
            ':only-child',
            ':parent',
            ':password',
            ':radio',
            ':reset',
            ':selected',
            ':submit'
            ':text'
            ':visible'
            
    }
}